<template>
  <resize-drawer
    :title="type === 'add' ? '新建字段' : '编辑字段'"
    :drawer="show"
    :size="drawerWidth"
    :isShowMoreBtn="true"
    @onCloseDraw="closeDraw"
    @onCancelFun="closeDraw"
    @onSave="subField"
  >
    <template #column>
      <el-form ref="formRef" :model="form" label-position="top" :rules="rules">
        <el-form-item label="字段类型" prop="type">
          <el-select-v2
            v-model="form.type"
            filterable
            clearable
            collapse-tags
            collapse-tags-tooltip
            :options="typeChoices"
            style="width: 100%"
            placeholder="请选择字段类型"
            :disabled="type !== 'add'"
            @change="typeChange"
          >
          </el-select-v2>
        </el-form-item>
        <el-form-item v-if="['radio', 'multi-select'].includes(form.type)" label="样式" prop="style">
          <el-radio-group v-model="form.style" :disabled="type !== 'add'">
            <el-radio :label="item.key" v-for="item in radioChoices" :key="item.key">{{ item.label }}</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item v-if="['cascade'].includes(form.type)" label="样式" prop="style">
          <el-radio-group v-model="form.style" :disabled="type !== 'add'">
            <el-radio :label="item.key" v-for="item in cascadeTypeChoices" :key="item.key">{{ item.label }}</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item
          v-if="['datetime', 'datetime-range'].includes(form.type)"
          label="样式"
          prop="style"
          :rules="[{ required: true, trigger: 'change', message: '请选择样式' }]"
        >
          <el-radio-group v-model="form.style" :disabled="type !== 'add'">
            <el-radio :label="item.key" v-for="item in dateTypeChoices" :key="item.key">{{ item.label }}</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="字段名称" prop="name">
          <el-input
            v-model.trim="form.name"
            placeholder="请输入字段名称"
            :maxlength="50"
            clearable
            show-word-limit
            :disabled="form.category === 'system'"
          ></el-input>
        </el-form-item>
        <el-form-item
          label="提示暗文"
          prop="placeholder"
          v-show="
            ['radio', 'multi-select'].includes(form.type)
              ? form.style === 'dropdown'
              : !['number', 'datetime-range'].includes(form.type)
          "
        >
          <el-input
            v-model.trim="form.placeholder"
            placeholder="请输入提示暗文"
            :maxlength="50"
            clearable
            show-word-limit
          ></el-input>
        </el-form-item>
        <el-form-item
          v-if="['cascade'].includes(form.type) && showOption"
          label="层级"
          prop="options.level"
          style="width: 100%"
        >
          <el-select v-model="form.options.level" filterable placeholder="请选择层级" @change="setLevel">
            <el-option :label="item" :value="item" v-for="item in [1, 2, 3, 4, 5]" :key="item"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item v-if="['radio', 'multi-select', 'cascade'].includes(form.type) && showOption">
          <template #label>
            <span style="color: #f56c6c; margin-right: 4px">*</span>
            选项
            <el-tooltip
              :content="form.type === 'cascade' ? '同一父级下子级选项不能重复' : '选项不能重复'"
              placement="top"
              effect="light"
            >
              <i style="color: #b3b9c7; cursor: pointer" class="MC_iconfont MC_icon-yiwen-xian"></i>
            </el-tooltip>
          </template>
          <Select ref="Select" v-if="form.type === 'radio'" :isSave="isSave" @onItemChange="previewChange"></Select>
          <Checkbox
            ref="MultiSelect"
            v-if="form.type === 'multi-select'"
            :isSave="isSave"
            @onItemChange="previewChange"
          ></Checkbox>
          <Cascader
            ref="Cascader"
            v-if="form.type === 'cascade'"
            :isSave="isSave"
            @onItemChange="previewChange"
          ></Cascader>
        </el-form-item>
        <!-- 级联单选展示 -->
        <el-form-item
          v-if="['cascade'].includes(form.type) && form.style === 'single'"
          label="层级必选"
          prop="options.fillLevel"
        >
          <el-checkbox v-model="form.options.fillLevel">必选全部层级</el-checkbox>
          <el-tooltip
            content="必选全部层级指当该字段为必填项时候，级联菜单的所有层级都必选，否则不能保存，非必选全部层级指选至任意一级即可"
            placement="top"
            effect="light"
            :show-after="500"
          >
            <i style="color: #b3b9c7; margin-left: 6px; cursor: pointer" class="MC_iconfont MC_icon-xinxi-mian"></i>
          </el-tooltip>
        </el-form-item>
        <el-form-item label="效果预览">
          <Preview
            :type="form.type"
            :label="form.name"
            :styleType="form.style"
            :fillLevel="Boolean(form.options && form.options.fillLevel)"
            :placeholder="form.placeholder"
            ref="Preview"
          />
        </el-form-item>
      </el-form>
    </template>
  </resize-drawer>
</template>

<script lang="ts">
import { defineComponent, getCurrentInstance, reactive, ref, toRefs, nextTick, watch } from 'vue'
import resizeDrawer from '@common/components/resize-drawer/index.vue'
import Preview from './preview.vue'
import Select from './select.vue'
import Checkbox from './checkbox.vue'
import Cascader from './cascader.vue'
import { addField, updateField } from '@app/base/apis/global-field'
import { ElMessage } from 'element-plus'
import { typeArr } from '../type'
import { deepClone } from '@/common/utils/common'
import mcCache from '@/common/utils/mc-get-cache'
import { getGender } from '@app/customer/utils/common'
interface State {
  form: any
  rules: Record<string, unknown>
  type: string
  showOption: boolean
  drawerWidth: number
  isSave: boolean
}
const defaultForm = {
  field: '',
  type: '',
  name: '',
  style: '',
  options: {
    children: [],
    fillLevel: false,
    level: 2
  } // 级联层级默认2
}
export default defineComponent({
  name: 'AddOrEditField',
  components: { resizeDrawer, Preview, Select, Checkbox, Cascader },
  emits: ['onUpdateFieldList'],
  setup(_, { emit }) {
    const instance: any = getCurrentInstance()
    const show = ref(false)

    const state: State = reactive({
      form: deepClone(defaultForm),
      rules: {
        type: [{ required: true, trigger: 'change', message: '请选择字段类型' }],
        name: [{ required: true, trigger: 'blur', message: '请输入字段名称' }],
        style: [{ required: true, trigger: 'change', message: '请选择样式' }],
        'options.level': [{ required: true, trigger: 'change', message: '请选择层级' }]
      },
      type: 'add',
      radioChoices: [
        { label: '下拉菜单', key: 'dropdown' },
        { label: '按钮平铺', key: 'tile' }
      ],
      cascadeTypeChoices: [
        { label: '单选', key: 'single' },
        { label: '多选', key: 'multi' }
      ],
      dateTypeChoices: [
        { label: '年月日', key: 'day' },
        { label: '年月日时分秒', key: 'second' }
      ],
      typeChoices: typeArr(),
      showOption: true,
      drawerWidth: 576,
      isSave: false // 点击的按钮为保存的按钮
    })

    const openDialog = async (type: string, row: any) => {
      // 打开抽屉
      show.value = true // 展开抽屉
      state.isSave = false
      state.type = type // 编辑、新建
      state.form = { ...deepClone(defaultForm), ...row }
      if (['radio', 'multi-select', 'cascade'].includes(state.form.type) && type === 'edit') {
        state.showOption = true
        if (row.category === 'system' && !row.choices && !row.options) {
          // 系统预置没有选项的不展示选项
          state.showOption = false
          if (state.form.type === 'cascade') {
            // 系统预置级联特殊处理
            state.form.options = {
              children: [],
              fillLevel: false,
              level: 2
            }
          }
          return
        }
        // 编辑选项回显
        await nextTick()
        if (state.form.type === 'radio') {
          if (row.field === 'gender') {
            row.choices.map((v: any) => {
              v.value = getGender[v.key]
            })
          }
          instance?.refs.Select &&
            instance?.refs.Select.setData(
              row.choices,
              row.choices && row.choices.filter((item: any) => item.isDefault),
              row.category === 'system'
            )
        } else if (state.form.type === 'multi-select') {
          instance?.refs.MultiSelect &&
            instance?.refs.MultiSelect.setData(row.choices, row.category === 'system' && row.field !== 'customerSource')
        } else {
          instance?.refs.Cascader && instance?.refs.Cascader.setData(row.options, row.category === 'system')
          state.form.options.fillLevel = Boolean(row.options && row.options.fillLevel)
        }
        previewChange(state.form.type === 'cascade' ? row.options : row.choices)
      }
    }

    // 提交
    const subField = () => {
      instance?.refs.formRef.validate((valid: boolean) => {
        if (valid) {
          state.isSave = true
          const { type, name, placeholder, field, style } = state.form
          const sendData: any = {
            type,
            name,
            placeholder,
            field
          }
          if (style) {
            // style不存在时不传
            sendData.style = style
          }
          // 校验选项有没有填
          if (['multi-select', 'radio'].includes(type) && state.showOption) {
            // 单选、多选
            sendData.choices = getOptionsData(type)
            if (sendData.choices && !sendData.choices.length) {
              return ElMessage.error('请填写选项')
            }
          } else if (['cascade'].includes(type) && state.showOption) {
            // 级联
            const options = getOptionsData(type)
            if (options.children && !options.children.length) {
              return ElMessage.error('请填写选项')
            } else {
              sendData.options = options
            }
          }
          ;(state.type === 'add' ? addField(sendData) : updateField(sendData))
            .then((res) => {
              if (res.success) {
                ElMessage.success('操作成功')
                show.value = false
                emit('onUpdateFieldList')
                // 更新pinia
                if (state.type === 'add') {
                  mcCache.$addOneCache('globalFieldCache', res.data, 'hasObj', 'field') // 新建
                } else {
                  mcCache.$updateCache('globalFieldCache', res.data, 'field', 'hasObj') // 编辑
                }
              }
            })
            .catch(() => {
              state.isSave = false
            })
        }
      })
    }

    const typeChange = (val: string) => {
      // style默认赋值
      const style = getStyle(val)
      state.form.style = style
    }

    // 获取样式默认值
    const getStyle = (type: string) => {
      switch (type) {
        case 'radio':
          return 'dropdown'
        case 'multi-select':
          return 'dropdown'
        case 'cascade':
          return 'single'
        case 'datetime':
          return 'second'
        case 'datetime-range':
          return 'second'
        default:
          return ''
      }
    }

    // 根据输入框类型返回不同的预览数据
    const getOptionsData = (type: string) => {
      switch (type) {
        case 'radio':
          return instance?.refs.Select.getData()
        case 'multi-select':
          return instance?.refs.MultiSelect.getData()
        case 'cascade':
          return {
            ...instance?.refs.Cascader.getData(),
            fillLevel: state.form.options.fillLevel ? state.form.options.level : 0
          }
        case 'number':
          return {
            value: undefined
          }
        default:
          return {}
      }
    }

    const closeDraw = () => {
      show.value = false
    }

    // 设置级联层级
    const setLevel = () => {
      instance?.refs.Cascader.setLevel(state.form.options.level)
    }

    watch(
      () => state.form.options && state.form.options.level,
      (val: number) => {
        switch (val) {
          case 1:
            state.drawerWidth = 576
            break
          case 2:
            state.drawerWidth = 576
            break
          case 3:
            state.drawerWidth = 694
            break
          case 4:
            state.drawerWidth = 902
            break
          case 5:
            state.drawerWidth = 1110
        }
      }
    )

    // 监听选项变化，渲染预览数据
    const previewChange = (group: any) => {
      instance?.refs.Preview.setData(group)
    }

    return {
      show,
      typeChange,
      openDialog,
      closeDraw,
      subField,
      previewChange,
      setLevel,
      ...toRefs(state)
    }
  }
})
</script>

<style lang="stylus" scoped>
.el-select
  width 100%
.el-form.el-form--default .el-form-item[role='group']
  margin-right 0
</style>
